package cube.data.util;

import java.util.ArrayList;
import java.util.List;

/**
 * SLIP帧处理
 * 
 * @author abiao
 */
public class SLIP {

    private static final byte END = (byte) 0xc0;
    private static final byte ESC = (byte) 0xdb;
    private static final byte ESC_END = (byte) 0xdc;
    private static final byte ESC_ESC = (byte) 0xdd;

    /**
     * 封帧
     */
    public static byte[] seal(byte[] data) {
        byte[] seal = new byte[data.length * 2 + 2];
        int p = 0;
        seal[p++] = END;
        for (int i = 0; i < data.length; i++) {
            if (data[i] == END) {
                seal[p++] = ESC;
                seal[p++] = ESC_END;
            } else if (data[i] == ESC) {
                seal[p++] = ESC;
                seal[p++] = ESC_ESC;
            } else {
                seal[p++] = data[i];
            }
        }
        seal[p++] = END;
        return DataUtil.copy(seal, 0, p);
    }

    /**
     * 解帧
     */
    public static byte[] unseal(byte[] data) {
        if (data.length < 3 || data[0] != END || data[data.length - 1] != END) {
            return new byte[0];
        }

        byte[] unseal = new byte[data.length];
        int p = 0;
        for (int i = 1; i < data.length - 1; i++) {
            if (data[i] == ESC) {
                if (data[i + 1] == ESC_END) {
                    unseal[p++] = END;
                }
                if (data[i + 1] == ESC_ESC) {
                    unseal[p++] = ESC;
                }
                i++;
            } else {
                unseal[p++] = data[i];
            }
        }
        return DataUtil.copy(unseal, 0, p);
    }

    /**
     * SLIP帧分割
     */
    @Deprecated
    public static List<byte[]> split(byte[] data) {
        List<byte[]> list = new ArrayList<byte[]>();

        int c0Flag = -1;
        for (int i = 0; i < data.length; i++) {
            if (data[i] == END) {
                if (c0Flag >= 0 && i - c0Flag > 1) {
                    byte[] bytes = new byte[i - c0Flag + 1];
                    System.arraycopy(data, c0Flag, bytes, 0, bytes.length);
                    list.add(bytes);
                }
                c0Flag = i;
            }
        }
        return list;
    }
}
